#ifndef OBJ_H
#define OBJ_H

#include <iostream>
#include <vector>
#include "vector.h"
#include "frustum.h"
using namespace std;

class CVector3 
{
public:
	float x, y, z;
};

class CVector2 
{
public:
	float x, y;
};

// This is our face structure.  This is is used for indexing into the vertex 
// and texture coordinate arrays.  From this information we know which vertices
// from our vertex array go to which face, along with the correct texture coordinates.
struct Face
{
	int vertIndex[3];			// indicies for the verts that make up this triangle
	int coordIndex[3];			// indicies for the tex coords to texture this face
};

// This holds the information for a material.  It may be a texture map of a color.
// Some of these are not used, but I left them because you will want to eventually
// read in the UV tile ratio and the UV tile offset for some models.
struct MaterialInfo
{
	char  strName[255];			// The texture name
	char  strFile[255];			// The texture file name (If this is set it's a texture map)
	short  color[3];			// The color of the object (R, G, B)
	int   texureId;				// the texture ID
} ;

// This holds all the information for our model/scene
struct t3DObject 
{
	//t3DObject();
	int  r, g, b;
	void setColor(int _r, int _g, int _b);
	int  numberOfVertices;			// The number of verts in the model
	int  numberOfFaces;			// The number of faces in the model
	int  numberOfTexVertices;		// The number of texture coordinates
	int  materialID;			// The texture ID to use, which is the index into our texture array
	bool hasTexture;			// This is TRUE if there is a texture map for this object
	char strName[255];			// The name of the object
	CVector3  *vertices;			// The object's vertices
	CVector3  *pNormals;		// The object's normals
	CVector2  *textureVertices;		// The texture's UV coordinates
	Face *faces;				// The faces information of the object
	string name;				//object name
};

// This holds our model information
class t3DModel 
{
public:
	t3DModel()
	{
		g_Texture[0] = 0;
	};
	void setColor(int _r, int _g, int _b);
	int numOfObjects;					// The number of objects in the model
	int numOfMaterials;					// The number of materials for the model
	vector<MaterialInfo> materials;	// The list of material information (Textures and colors)
	vector<t3DObject> object;			// The object list for our model
	UINT g_Texture[100];
	void draw(float a, float b, float c);
};

class ObjLoader
{
public:
	vector<CVector3>  vertices;

	// Loads the file having the fileName name
	bool importObj(t3DModel *model, char *fileName);
	void readObjFile(t3DModel *model);

	// This is called in readObjFile() if we find a line starting with 'v'
	void readVertexInfo();

	// This is called in readObjFile() if we find a line starting with 'f'
	void readFaceInfo();

	//This is called in readObjFile() if we find a line starting with 'o'
	void readName();

	//This is called in readObjFile() if we find a line starting with 'u'
	void readMaterialInfo();
	// This is called when we are finished loading in the face information
	void fillInObjectInfo(t3DModel *model);

	// This isn't necessary for the loader, but it's nice to have vertex normals for lighting
	void computeNormals(t3DModel *model);

	void createTexture(UINT *, LPSTR, int);

	// To make it easier to assign a material to a .obj object we create a funtion to do so.
	// We can pass in the model, the material name, the texture file name and the RGB colors.
	// If we just want a color, pass in NULL for strFile.
	void addMaterial(t3DModel *model, char *strName, char *strFile, 
					 int r = 255,      int g = 255,   int b = 255);

private:

	// This holds our file pointer for reading in the file
	FILE *filePointer;

	// This is an STL vector that holds a list of vertices
	//vector<CVector3>  vertices;

	string name;

	char t_name[255], t_path[255];
	
	// This is an STL vector that holds a list of faces
	vector<Face> faces;

	// This is an STL vector that holds a list of UV Coordinates
	vector<CVector2>  textureCoordinates;

	// This tells us if the current object has texture coordinates
	bool objectHasUV;

	// This tells us if we just read in face data so we can keep track of multiple objects
	bool justReadAFace;
};


#endif //OBJ_H